#ifndef __HAL_UART_H__
#define __HAL_UART_H__

#include "gbl_types.h"
#include "os_api.h"
/*===========================================================================

                          Type definition.

===========================================================================*/

typedef enum /* The number of ports in the UART  */
{
    UART_PORT_1,
    UART_PORT_2, // main uart
    UART_PORT_3,    
    UART_PORT_4,
    NUMBER_OF_PORTS,
} UART_Port;

typedef enum /* All the UART Baud Rate that the UART Package supplay */
{
    UART_BAUD_150 = 150,
    UART_BAUD_300 = 300,
    UART_BAUD_600 = 600,
    UART_BAUD_1200 = 1200,
    UART_BAUD_2400 = 2400,
    UART_BAUD_3600 = 3600,
    UART_BAUD_4800 = 4800,
    UART_BAUD_7200 = 7200,
    UART_BAUD_9600 = 9600,
    UART_BAUD_14400 = 14400,
    UART_BAUD_19200 = 19200,
    UART_BAUD_28800 = 28800,
    UART_BAUD_38400 = 38400,
    UART_BAUD_57600 = 57600,
    UART_BAUD_115200 = 115200,
    UART_BAUD_230400 = 230400,
    UART_BAUD_460800 = 460800,
    UART_BAUD_921600 = 921600,
    UART_BAUD_1842000 = 1842000,
    UART_BAUD_3686400 = 3686400,
    UART_MAX_NUM_BAUD
} UART_BaudRates;

typedef enum
{
    UART_PARITY_NONE = 0,
    UART_PARITY_ODD   = 1,
    UART_PARITY_EVEN  = 3,
} UART_PARITY_TYPE;

typedef enum
{
    UART_DATA_5 = 0,
    UART_DATA_6 = 1,
    UART_DATA_7 = 2,
    UART_DATA_8 = 3,
} UART_DATA_WIDTH;

typedef enum
{
    UART_ONE_STOPBIT = 0,
    UART_ONE_HALF_OR_TWO_STOPBITS = 1,
}UART_STOPBIT;

typedef struct
{
    UINT32 length;
    UINT8 *data;
} UartRxMsg_Type;

/*===========================================================================

                          INTERNAL FUNCTION DECLARATIONS

===========================================================================*/


/*****************************************************************
* Function: hal_UartOpenCb
*
* Description:
* 	该函数用于打开 UART 设备，通过回调函数接收数据。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	baud      	[in] 	波特率设置。
* 	uart_cb  	[in] 	接收数据的回调函数。
* Return:
* 	None
*
*****************************************************************/
void hal_UartOpenCb(UART_Port portNumber, UART_BaudRates baud, void  (*uart_cb)(UINT8 *, UINT32));


/*****************************************************************
* Function: hal_UartOpenCbEx
*
* Description:
* 	该函数用于打开 UART 设备并进行相关属性配置，通过回调函数接收数据。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	baud      	[in] 	波特率设置。
* 	parity     	[in] 	UART_PARITY_TYPE。
* 	datawidth  	[in] 	UART_DATA_WIDTH。
* 	stopbit    	[in] 	UART_STOPBIT。
* 	dma     	[in] 	是否启用DMA。
* 	uart_cb  	[in] 	接收数据的回调函数。
* Return:
* 	None
*
*****************************************************************/
void hal_UartOpenCbEx(UART_Port portNumber, 
							UART_BaudRates baud, 
							UART_PARITY_TYPE parity,
							UART_DATA_WIDTH datawidth,
							UART_STOPBIT stopbit,
							BOOL dma,
							void  (*uart_cb)(UINT8 *, UINT32));

/*****************************************************************
* Function: hal_UartOpen
*
* Description:
* 	该函数用于打开 UART 设备并通过消息队列接收数据。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	baud      	[in] 	波特率设置。
* 	uartMsgQ  	[in] 	接收数据的消息队列。
* Return:
* 	None
*
*****************************************************************/
void hal_UartOpen(UART_Port portNumber, UART_BaudRates baud, OSMsgQRef uartMsgQ);


/*****************************************************************
* Function: hal_UartClose
*
* Description:
* 	该函数用于关闭 UART 设备。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* Return:
* 	None
*
*****************************************************************/
void hal_UartClose(UART_Port portNumber);


/*****************************************************************
* Function: hal_UartWrite
*
* Description:
* 	该函数用于通过 UART 发送数据。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	bufPtr   	[In] 	发送数据内容。
* 	length   	[In] 	发送数据长度。
* Return:
* 	None
*
*****************************************************************/
void hal_UartWrite(UART_Port portNumber, UINT8 *bufPtr, UINT32 length);

/*****************************************************************
* Function: hal_UartWriteEx
*
* Description:
* 	该函数用于通过 UART 发送数据,并返回发送数据长度。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	bufPtr   	[In] 	发送数据内容。
* 	length   	[In] 	发送数据长度。
* Return:
* 	发送成功的数据长度
*
*****************************************************************/
UINT32 hal_UartWriteEx(UART_Port portNumber, UINT8 *bufPtr, UINT32 length);

/*****************************************************************
* Function: hal_UartEnableGpio
*
* Description:
* 	该函数用于使能 UART 对应的 gpio， 暂时只对UART3生效。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	rx_gpio   	[In] 	UART Rx对应的GPIO。
* 	tx_gpio   	[In] 	UART Tx对应的GPIO。
* Return:
* 	None
*
*****************************************************************/
void hal_UartEnableGpio(UART_Port portNumber, UINT8 rx_gpio, UINT8 tx_gpio);

/*****************************************************************
* Function: hal_UartEnableGpio
*
* Description:
* 	该函数用于去使能 UART 对应的 gpio， 暂时只对UART3生效，多组UART3切换使用的话，需要先disable掉之前的uart3，再enable需要使用的另外一组uart3，详见demo4.2。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	rx_gpio   	[In] 	UART Rx对应的GPIO。
* 	tx_gpio   	[In] 	UART Tx对应的GPIO。
* Return:
* 	None
*
*****************************************************************/
void hal_UartDisableGpio(UART_Port portNumber, UINT8 rx_gpio, UINT8 tx_gpio);


/*****************************************************************
* Function: hal_UartWaitFifoEmpty
*
* Description:
* 	该函数用于uart发送数据后，等待fifo数据全部发送完成，主要用于 485 芯片手动切换数据方向使用。
* 
* Parameters:
* 	portNumber 	[In] 	串口选择。
* 	rx_gpio   	[In] 	UART Rx对应的GPIO。
* 	tx_gpio   	[In] 	UART Tx对应的GPIO。
* Return:
* 	0： fifo已清空
*   -1：等待超时，fifo可能还未清空
*****************************************************************/
int hal_UartWaitFifoEmpty(UART_Port portNumber, UINT32 timeout_ms);


#endif
